import React, {
  createContext,
  useContext,
  useState,
  useCallback,
  useMemo,
  ReactNode,
  useEffect,
} from "react";
import { Space, Spin, message } from "antd";
import { LoadingOutlined } from "@ant-design/icons";

// 1. 定义 Context 值的类型
interface GlobalLoadingContextType {
  open: (text?: string) => void;
  close: () => void;
}

// 2. 创建 Context 并指定类型
const GlobalLoadingContext = createContext<
  GlobalLoadingContextType | undefined
>(undefined);

// 3. 定义 Provider 的 props 类型
interface GlobalLoadingProviderProps {
  children: ReactNode;
}

// 4. 创建 Context 的 Provider 组件
export const GlobalLoadingProvider: React.FC<GlobalLoadingProviderProps> = ({
  children,
}) => {
  const [loading, setLoading] = useState<boolean>(false);
  const [loadingText, setLoadingText] = useState<string>("加载中...");
  useEffect(() => {
    // 监听打开 Loading 的事件
    const handleOpen = (event: CustomEvent<string>): void => {
      setLoadingText(event.detail || "加载中...");
      setLoading(true);
    };
    // 监听关闭 Loading 的事件
    const handleClose = (): void => {
      setLoading(false);
    };
    window.addEventListener("globalLoadingOpen", handleOpen as EventListener);
    window.addEventListener("globalLoadingClose", handleClose as EventListener);
  }, []);

  // 显示 Loading
  const open = useCallback((text: string = "加载中...") => {
    setLoadingText(text);
    setLoading(true);
  }, []);

  // 隐藏 Loading
  const close = useCallback(() => {
    setLoading(false);
  }, []);

  // 通过 useMemo 优化，避免不必要的重渲染
  const contextValue: GlobalLoadingContextType = useMemo(
    () => ({ open, close }),
    [open, close]
  );

  return (
    <GlobalLoadingContext.Provider value={contextValue}>
      {children}
      {/* 全局 Loading 层 */}
      {loading && (
        <div
          style={{
            position: "fixed",
            top: 0,
            left: 0,
            width: "100vw",
            height: "100vh",
            backgroundColor: "rgba(0, 0, 0, 0.5)",
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            zIndex: 9999,
          }}
        >
          <Space direction="vertical" align="center">
            <Spin size="large" />
            <span style={{ color: "#fff" }}>{loadingText}</span>
          </Space>
        </div>
      )}
    </GlobalLoadingContext.Provider>
  );
};

// 5. 自定义 Hook，方便在任何组件中使用
export const useGlobalLoading = (): GlobalLoadingContextType => {
  const context = useContext(GlobalLoadingContext);
  if (!context) {
    throw new Error(
      "useGlobalLoading must be used within a GlobalLoadingProvider"
    );
  }
  return context;
};

// 6. 创建直接调用的工具函数对象
interface LoadingUtilsType {
  open: (text?: string) => void;
  close: () => void;
}

export const loading: LoadingUtilsType = {
  open: (text?: string) => {
    window.dispatchEvent(
      new CustomEvent("globalLoadingOpen", { detail: text })
    );
  },
  close: () => {
    window.dispatchEvent(new CustomEvent("globalLoadingClose"));
  },
};
